package com.cbs.android.widget.attextview;

import android.content.Context;
import android.os.Build;
import android.os.Parcel;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.style.URLSpan;
import android.util.AttributeSet;
import android.view.View;

import com.cbs.android.widget.attextview.movementmethod.AtTextViewLinkMovementMethod;
import com.cbs.android.widget.nospacetextview.NoSpaceTextView;

import static android.text.Html.FROM_HTML_MODE_LEGACY;

/**
 * Created by broche on 6/23/16.
 */
public class AtTextView extends NoSpaceTextView {
    private LinkStyle linkStyle = null;
    private OnClickListener onClickListener;
    private boolean hrefClickFlag = false;

    public AtTextView(Context context) {
        super(context);
        init();
    }

    public AtTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public AtTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            setHighlightColor(getResources().getColor(R.color.cbs_attextview_link_background, null));
        } else {
            setHighlightColor(getResources().getColor(R.color.cbs_attextview_link_background));
        }
    }

    public void setLinkStyle(LinkStyle linkStyle) {
        this.linkStyle = linkStyle;
        setHighlightColor(linkStyle.getBackgroundColor());
    }

    public void loadContent(String content) {
        boolean flag = false;
        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder nameBuilder = new StringBuilder();
        StringBuilder hrefBuilder = new StringBuilder();
        for (int i = 0; i < content.length(); i++) {
            if (!flag) {
                if (content.charAt(i) == '@') {
                    flag = true;
                    nameBuilder.append(content.charAt(i));
                } else {
                    stringBuilder.append(content.charAt(i));
                }
            } else {
                if (content.charAt(i) == ' ') {
                    nameBuilder.append(content.charAt(i));
                    flag = false;
                    stringBuilder.append("<a href='");
                    stringBuilder.append(hrefBuilder.toString().trim());
                    stringBuilder.append("'>");
                    stringBuilder.append(nameBuilder.toString().trim());
                    stringBuilder.append("</a>");
                    nameBuilder = new StringBuilder();
                    hrefBuilder = new StringBuilder();
                } else {
                    nameBuilder.append(content.charAt(i));
                    hrefBuilder.append(content.charAt(i));
                }
            }
        }
        if (flag) {
            stringBuilder.append("<a href='");
            stringBuilder.append(hrefBuilder.toString());
            stringBuilder.append("'>");
            stringBuilder.append(nameBuilder.toString());
            stringBuilder.append("</a>");
        }
        String result = stringBuilder.toString();
        result = result.replace("\r\n", "<br />");
        result = result.replace("\n", "<br />");

        // generate spannable
        Spanned spanned;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            spanned = Html.fromHtml(result, FROM_HTML_MODE_LEGACY);
        } else {
            spanned = Html.fromHtml(result);
        }
        SpannableStringBuilder builder = new SpannableStringBuilder(spanned);
        URLSpan[] urlSpans = spanned.getSpans(0, result.length(), URLSpan.class);
        setMovementMethod(AtTextViewLinkMovementMethod.getInstance());
        if (urlSpans.length > 0) {
            for (URLSpan urlSpan : urlSpans) {
                int start = builder.getSpanStart(urlSpan);
                int end = builder.getSpanEnd(urlSpan);
                builder.removeSpan(urlSpan);
                MyUrlSpan myUrlSpan = new MyUrlSpan(urlSpan.getURL());
                builder.setSpan(myUrlSpan, start, end, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
            }
        }

        // set content
        setText(builder);
    }

    public void setOnClickListener(OnClickListener listener) {
        this.onClickListener = listener;
        setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (hrefClickFlag) {
                    hrefClickFlag = false;
                } else {
                    if (onClickListener != null) {
                        onClickListener.onClick(v);
                    }
                }
            }
        });
    }

    private class MyUrlSpan extends URLSpan {
        public MyUrlSpan(String url) {
            super(url);
        }

        @Override
        public void onClick(View widget) {
            if (onClickListener != null) {
                onClickListener.onLink(widget, getURL());
            }
            hrefClickFlag = true;
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            if (linkStyle != null) {
                linkStyle.updateDrawState(ds);
            } else {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    ds.setColor(getResources().getColor(R.color.cbs_attextview_link_color, null));
                } else {
                    ds.setColor(getResources().getColor(R.color.cbs_attextview_link_color));
                }
                ds.setUnderlineText(getResources().getBoolean(R.bool.cbs_attextview_link_underline));
            }
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
        }

        protected MyUrlSpan(Parcel in) {
            super(in);
        }

        public final Creator<MyUrlSpan> CREATOR = new Creator<MyUrlSpan>() {
            @Override
            public MyUrlSpan createFromParcel(Parcel source) {
                return new MyUrlSpan(source);
            }

            @Override
            public MyUrlSpan[] newArray(int size) {
                return new MyUrlSpan[size];
            }
        };
    }

    public interface OnClickListener {
        void onClick(View v);

        void onLink(View v, String href);
    }

    public interface LinkStyle {
        void updateDrawState(TextPaint ds);

        int getBackgroundColor();
    }
}
